package com.zh.harmony.fragment;

import ohos.agp.components.Component;
import ohos.agp.components.ComponentContainer;
import ohos.agp.components.ComponentParent;
import ohos.agp.components.LayoutScatter;
import ohos.app.Context;
import ohos.eventhandler.EventHandler;
import ohos.eventhandler.EventRunner;

import java.util.LinkedList;
import java.util.List;

/**
 * Fragment管理器
 */
public class FragmentManager {
    /**
     * 生命周期分发器
     */
    private final FragmentLifecycleDispatcher mFragmentLifecycleDispatcher = new FragmentLifecycleDispatcher(this);
    /**
     * 父FragmentManager
     */
    private FragmentManager mParentFragmentManager;
    /**
     * 子Fragment列表
     */
    final List<Fragment> mFragments = new LinkedList<>();
    /**
     * 放置Fragment的容器
     */
    private FragmentContainer mFragmentContainer;
    /**
     * FragmentAbility实例
     */
    private FragmentAbility mFragmentAbility;
    /**
     * 主线程Handler
     */
    private EventHandler mMainHandler = new EventHandler(EventRunner.getMainEventRunner());

    public FragmentManager(FragmentAbility ability) {
        attachFragmentAbility(ability);
    }

    public void attachFragmentAbility(FragmentAbility ability) {
        this.mFragmentAbility = ability;
        this.mFragmentContainer = new FragmentContainer() {
            @Override
            public Component findViewById(int viewId) {
                return ability.findComponentById(viewId);
            }
        };
    }

    public FragmentManager(FragmentManager parentFragmentManager, Fragment fragment) {
        this.mFragmentAbility = fragment.getAbility();
        this.mParentFragmentManager = parentFragmentManager;
        this.mFragmentContainer = new FragmentContainer() {
            @Override
            public Component findViewById(int viewId) {
                return fragment.getView().findComponentById(viewId);
            }
        };
    }

    private interface FragmentContainer {
        Component findViewById(int viewId);
    }

    /**
     * 开启事务
     */
    public FragmentTransaction beginTransaction() {
        return new BackStackRecord(this);
    }

    /**
     * 获取父FragmentManager
     */
    public FragmentManager getParentFragmentManager() {
        return mParentFragmentManager;
    }

    //-------------------------- 公开操作API --------------------------

    public void attachFragment(Fragment fragment) {
        if (fragment.getView() != null) {
            if (fragmentIsAdd(fragment)) {
                return;
            }
        }
        addFragment(fragment);
    }

    public void detachFragment(Fragment fragment) {
        if (fragment.getView() != null) {
            if (!fragmentIsAdd(fragment)) {
                return;
            }
        }
        removeFragment(fragment);
    }

    public void addFragment(Fragment fragment) {
        ComponentContainer containerView = findViewById(fragment.mContainerId);
        if (containerView == null) {
            throw new NullPointerException("容器Id不能为空");
        }
        if (fragment.getView() != null) {
            ComponentParent parent = fragment.getView().getComponentParent();
            if (parent != null) {
                parent.removeComponent(fragment.getView());
            }
        }
        //通知依附
        fragment.onAttach(getContext());
        //创建View
        Component rootView = fragment.performCreateView(LayoutScatter.getInstance(getContext()), containerView);
        if (rootView != null) {
            containerView.addComponent(rootView);
        }
        fragment.isAdd = true;
        fragment.setFragmentManager(this);
        //通知创建
        fragment.onCreate();
        fragment.onViewCreated(fragment.getView());
        //切换可见性
        fragment.visibleChange(true);
        mFragments.add(fragment);
    }

    public void showFragment(Fragment fragment) {
        if (fragment.getView() != null) {
            fragment.getView().setVisibility(Component.VISIBLE);
            fragment.isVisible = true;
            fragment.visibleChange(true);
        }
    }

    public void hideFragment(Fragment fragment) {
        if (fragment.getView() != null) {
            fragment.getView().setVisibility(Component.INVISIBLE);
            fragment.isVisible = false;
            fragment.visibleChange(false);
        }
    }

    public void replaceFragment(Fragment fragment) {
        //先查找Fragment是否存在，存在则先移除
        Fragment currentFragment = findFragmentById(fragment.mContainerId);
        if (currentFragment != null) {
            if (currentFragment == fragment) {
                return;
            }
            removeFragment(fragment);
        }
        addFragment(fragment);
    }

    public void removeFragment(Fragment fragment) {
        //遍历查找目标Fragment
        Fragment target = null;
        for (Fragment fa : mFragments) {
            if (fa == fragment) {
                target = fa;
                break;
            }
        }
        if (target == null) {
            return;
        }
        //移除处理
        target.onDestroy();
        ComponentContainer container = findViewById(target.mContainerId);
        if (container != null) {
            container.removeComponent(target.getView());
        }
        target.isVisible = false;
        target.visibleChange(false);
        mFragments.remove(target);
    }

    /**
     * 异步执行一个操作
     */
    public void enqueueAction(Runnable action) {
        mMainHandler.postTask(action);
    }

    /**
     * 判断Fragment是否添加了
     */
    boolean fragmentIsAdd(Fragment fragment) {
        for (Fragment fa : mFragments) {
            if (fa == fragment) {
                return true;
            }
        }
        return false;
    }

    /**
     * 根据Id查找Fragment
     */
    public Fragment findFragmentById(int id) {
        for (int i = mFragments.size() - 1; i > -1; i--) {
            if (mFragments.get(i).mContainerId == id) {
                return mFragments.get(i);
            }
        }
        return null;
    }

    /**
     * 根据Tag查找Fragment
     */
    public Fragment findFragmentByTag(String tag) {
        for (int i = mFragments.size() - 1; i > -1; i--) {
            if (TextUtils.equals(mFragments.get(i).mTag, tag)) {
                return mFragments.get(i);
            }
        }
        return null;
    }

    public boolean findFragment(Fragment fragment) {
        for (int i = mFragments.size() - 1; i > -1; i--) {
            if (fragment == mFragments.get(i)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 查找放置Fragment的View容器
     *
     * @param viewId View容器Id
     */
    private ComponentContainer findViewById(int viewId) {
        return (ComponentContainer) mFragmentContainer.findViewById(viewId);
    }

    public FragmentLifecycleDispatcher getFragmentLifecycleDispatcher() {
        return mFragmentLifecycleDispatcher;
    }

    public FragmentAbility getAbility() {
        return mFragmentAbility;
    }

    public Context getContext() {
        return mFragmentAbility;
    }

    private static final class TextUtils {
        private static boolean equals(CharSequence a, CharSequence b) {
            if (a == b) return true;
            int length;
            if (a != null && b != null && (length = a.length()) == b.length()) {
                if (a instanceof String && b instanceof String) {
                    return a.equals(b);
                } else {
                    for (int i = 0; i < length; i++) {
                        if (a.charAt(i) != b.charAt(i)) return false;
                    }
                    return true;
                }
            }
            return false;
        }
    }
}